Skip to content

Commit

Permalink
add CTE examples to site
Browse files Browse the repository at this point in the history
  • Loading branch information
koskimas committed Mar 31, 2024
1 parent 4326a91 commit d9a53cd
Show file tree
Hide file tree
Showing 7 changed files with 160 additions and 2 deletions.
2 changes: 1 addition & 1 deletion site/docs/examples/INSERT/0040-complex-values.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const result = await db
.insertInto('person')
.values(({ ref, selectFrom, fn }) => ({
first_name: 'Jennifer',
last_name: sql\`concat(\${ani}, \${ston})\`,
last_name: sql<string>\`>concat(\${ani}, \${ston})\`,
middle_name: ref('first_name'),
age: selectFrom('person')
.select(fn.avg<number>('age').as('avg_age')),
Expand Down
21 changes: 21 additions & 0 deletions site/docs/examples/cte/0010-simple-selects.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
export const simpleSelects = `const result = await db
// Create a CTE called \`jennifers\` that selects all
// persons named 'Jennifer'.
.with('jennifers', (db) => db
.selectFrom('person')
.where('first_name', '=', 'Jennifer')
.select(['id', 'age'])
)
// Select all rows from the \`jennifers\` CTE and
// further filter it.
.with('adult_jennifers', (db) => db
.selectFrom('jennifers')
.where('age', '>', 18)
.select(['id', 'age'])
)
// Finally select all adult jennifers that are
// also younger than 60.
.selectFrom('adult_jennifers')
.where('age', '<', 60)
.selectAll()
.execute()`
27 changes: 27 additions & 0 deletions site/docs/examples/cte/0010-simple-selects.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
title: 'Simple selects'
---

# Simple selects

Common table expressions (CTE) are a great way to modularize complex queries.
Essentially they allow you to run multiple separate queries within a
single roundtrip to the DB.

Since CTEs are a part of the main query, query optimizers inside DB
engines are able to optimize the overall query. For example, postgres
is able to inline the CTEs inside the using queries if it decides it's
faster.

import {
Playground,
exampleSetup,
} from '../../../src/components/Playground'

import {
simpleSelects
} from './0010-simple-selects'

<div style={{ marginBottom: '1em' }}>
<Playground code={simpleSelects} setupCode={exampleSetup} />
</div>
28 changes: 28 additions & 0 deletions site/docs/examples/cte/0020-inserts-updates-and-deletions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
export const insertsUpdatesAndDeletions = `const result = await db
.with('new_person', (db) => db
.insertInto('person')
.values({
first_name: 'Jennifer',
age: 35,
})
.returning('id')
)
.with('new_pet', (db) => db
.insertInto('pet')
.values({
name: 'Doggo',
species: 'dog',
is_favorite: true,
// Use the id of the person we just inserted.
owner_id: db
.selectFrom('new_person')
.select('id')
})
.returning('id')
)
.selectFrom(['new_person', 'new_pet'])
.select([
'new_person.id as person_id',
'new_pet.id as pet_id'
])
.execute()`
21 changes: 21 additions & 0 deletions site/docs/examples/cte/0020-inserts-updates-and-deletions.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
title: 'Inserts, updates and deletions'
---

# Inserts, updates and deletions

Some databases like postgres also allow you to run other queries than selects
in CTEs. On these databases CTEs are extremely powerful:

import {
Playground,
exampleSetup,
} from '../../../src/components/Playground'

import {
insertsUpdatesAndDeletions
} from './0020-inserts-updates-and-deletions'

<div style={{ marginBottom: '1em' }}>
<Playground code={insertsUpdatesAndDeletions} setupCode={exampleSetup} />
</div>
8 changes: 8 additions & 0 deletions site/docs/examples/cte/_category_.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"label": "CTE",
"position": 7,
"link": {
"type": "generated-index",
"description": "Short and simple examples of how to use common table expressions (CTE) in queries."
}
}
55 changes: 54 additions & 1 deletion src/query-creator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -564,24 +564,77 @@ export class QueryCreator<DB> {
*
* ### Examples
*
* <!-- siteExample("cte", "Simple selects", 10) -->
*
* Common table expressions (CTE) are a great way to modularize complex queries.
* Essentially they allow you to run multiple separate queries within a
* single roundtrip to the DB.
*
* Since CTEs are a part of the main query, query optimizers inside DB
* engines are able to optimize the overall query. For example, postgres
* is able to inline the CTEs inside the using queries if it decides it's
* faster.
*
* ```ts
* await db
* const result = await db
* // Create a CTE called `jennifers` that selects all
* // persons named 'Jennifer'.
* .with('jennifers', (db) => db
* .selectFrom('person')
* .where('first_name', '=', 'Jennifer')
* .select(['id', 'age'])
* )
* // Select all rows from the `jennifers` CTE and
* // further filter it.
* .with('adult_jennifers', (db) => db
* .selectFrom('jennifers')
* .where('age', '>', 18)
* .select(['id', 'age'])
* )
* // Finally select all adult jennifers that are
* // also younger than 60.
* .selectFrom('adult_jennifers')
* .where('age', '<', 60)
* .selectAll()
* .execute()
* ```
*
* <!-- siteExample("cte", "Inserts, updates and deletions", 20) -->
*
* Some databases like postgres also allow you to run other queries than selects
* in CTEs. On these databases CTEs are extremely powerful:
*
* ```ts
* const result = await db
* .with('new_person', (db) => db
* .insertInto('person')
* .values({
* first_name: 'Jennifer',
* age: 35,
* })
* .returning('id')
* )
* .with('new_pet', (db) => db
* .insertInto('pet')
* .values({
* name: 'Doggo',
* species: 'dog',
* is_favorite: true,
* // Use the id of the person we just inserted.
* owner_id: db
* .selectFrom('new_person')
* .select('id')
* })
* .returning('id')
* )
* .selectFrom(['new_person', 'new_pet'])
* .select([
* 'new_person.id as person_id',
* 'new_pet.id as pet_id'
* ])
* .execute()
* ```
*
* The CTE name can optionally specify column names in addition to
* a name. In that case Kysely requires the expression to retun
* rows with the same columns.
Expand Down

0 comments on commit d9a53cd

Please sign in to comment.